Skip to content

Conversation

@marki1an
Copy link
Collaborator

@marki1an marki1an commented Dec 24, 2025

🔧 Type of changes

  • new bid adapter
  • bid adapter update
  • new feature
  • new analytics adapter
  • new module
  • module update
  • bugfix
  • documentation
  • configuration
  • dependency update
  • tech debt (test coverage, refactorings, etc.)

✨ What's the context?

What's the context for the changes?

🧠 Rationale behind the change

Why did you choose to make these changes? Were there any trade-offs you had to consider?

🔎 New Bid Adapter Checklist

  • verify email contact works
  • NO fully dynamic hostnames
  • geographic host parameters are NOT required
  • direct use of HTTP is prohibited - implement an existing Bidder interface that will do all the job
  • if the ORTB is just forwarded to the endpoint, use the generic adapter - define the new adapter as the alias of the generic adapter
  • cover an adapter configuration with an integration test

🧪 Test plan

How do you know the changes are safe to ship to production?

🏎 Quality check

  • Are your changes following our code style guidelines?
  • Are there any breaking changes in your code?
  • Does your test coverage exceed 90%?
  • Are there any erroneous console logs, debuggers or leftover code in your changes?

@marki1an marki1an self-assigned this Dec 24, 2025
@marki1an marki1an added the tests Functional or other tests label Dec 24, 2025
@osulzhenko osulzhenko self-requested a review January 2, 2026 09:18
@osulzhenko osulzhenko added the work in progress Signals not finished work label Jan 2, 2026
@marki1an marki1an changed the base branch from master to secondary-bidders January 7, 2026 14:03
@marki1an marki1an removed the work in progress Signals not finished work label Jan 7, 2026
Copy link
Collaborator

@osulzhenko osulzhenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure the test waits for all primary bidders to respond. We need to ensure the code waits for the last one, not the first. Please add a test case with two primary bidders and one secondary bidder to the spec

OPENX("openx"),
AMX("amx"),
AMX_UPPER_CASE("AMX"),
OPENX_ALIAS("openxalias"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not regular alias?

Comment on lines 30 to 31
protected static final Bidder openXBidder = new Bidder(networkServiceContainer, "/openx-auction")
protected static final Bidder openXAliasBidder = new Bidder(networkServiceContainer, "/openx-alias-auction")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private

protected static final Bidder openXAliasBidder = new Bidder(networkServiceContainer, "/openx-alias-auction")

@Shared
PrebidServerService pbsServiceWithOpenXAndIXBidder = pbsServiceFactory.getService(OPENX_CONFIG + OPENX_ALIAS_CONFIG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pbsServiceWithOpenXBidder

assert !bidResponse.ext.seatnonbid
}

def "PBS should emit a warning when null in secondary bidders config"() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't?

openXAliasBidder.reset()
}

def "PBS shouldn't wait on secondary bidder when alias bidder respond with dilay"() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty similar to def "PBS shouldn't treated alias bidder as secondary when root bidder code in secondary"

accountDao.save(account)

and: "Set up openx bidder response with delay"
openXBidder.setResponseWithDilay(5)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delay also should be constant

: HttpResponse.notFoundResponse()}
}

void setResponseWithDilay(Integer dilayTimeout = 5) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

Comment on lines 38 to 39
openXBidder.setResponse()
openXAliasBidder.setResponse()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we need to set response at end of spec

Comment on lines 23 to 24
"adapters.openx.enabled" : "true",
"adapters.openx.endpoint": "$networkServiceContainer.rootUri/openx-auction".toString()]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace openx with ${OPENX.value}

Comment on lines +32 to +33
private static final Bidder openXBidder = new Bidder(networkServiceContainer, "/openx-auction")
private static final Bidder genericAliasBidder = new Bidder(networkServiceContainer, "/generic-alias-auction")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use openx-auction and generic-alias-auction in several places. Please make them constants


cleanup: "Reset mock"
openXBidder.reset()
genericAliasBidder.reset()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls make cleanup as separate method

    @Override
    def cleanup() {
        openXBidder.reset()
        genericAliasBidder.reset()
    }

Comment on lines +70 to +119
def "PBS shouldn't emit a warning when empty secondary bidders config"() {
given: "Default basic BidRequest with generic bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
enabledReturnAllBidStatus()
}

and: "Account in the DB"
def accountConfig = AccountConfig.defaultAccountConfig.tap {
it.auction = new AccountAuctionConfig(secondaryBidders: [null])
}
def account = new Account(uuid: bidRequest.accountId, config: accountConfig)
accountDao.save(account)

when: "PBS processes auction request"
def bidResponse = pbsServiceWithOpenXBidder.sendAuctionRequest(bidRequest)

then: "PBs should processed bidder request"
assert bidder.getBidderRequest(bidRequest.id)

and: "PBS shouldn't contain errors, warnings and seat non bid"
assert !bidResponse.ext?.warnings
assert !bidResponse.ext?.errors
assert !bidResponse.ext?.seatnonbid
}

def "PBS shouldn't emit a warning when invalid bidder in secondary bidders config"() {
given: "Default basic BidRequest with generic bidder"
def bidRequest = BidRequest.defaultBidRequest.tap {
enabledReturnAllBidStatus()
}

and: "Account in the DB"
def accountConfig = AccountConfig.defaultAccountConfig.tap {
it.auction = new AccountAuctionConfig(secondaryBidders: [UNKNOWN])
}
def account = new Account(uuid: bidRequest.accountId, config: accountConfig)
accountDao.save(account)

when: "PBS processes auction request"
def bidResponse = pbsServiceWithOpenXBidder.sendAuctionRequest(bidRequest)

then: "PBs should processed bidder request"
def bidderRequests = bidder.getBidderRequests(bidRequest.id)
assert bidderRequests.size() == 1

and: "PBS shouldn't contain errors, warnings and seat non bid"
assert !bidResponse.ext?.warnings
assert !bidResponse.ext?.errors
assert !bidResponse.ext?.seatnonbid
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be combined with a where block to handle invalid secondary bidders

Comment on lines +160 to +163
def bidRequest = BidRequest.defaultBidRequest.tap {
it.imp[0].ext.prebid.bidder.openx = Openx.defaultOpenx
enabledReturnAllBidStatus()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add private method:


private void getEnrichedBidRequest(List<BidderName> bidderNames) {
    BidRequest.defaultBidRequest.tap {
        if (bidderNames.contains(OPENX)) {
            it.imp[0]?.ext?.prebid?.bidder?.openx = Openx.defaultOpenx
        }
        if (bidderNames.contains(ALIAS)) {
            it.imp[0]?.ext?.prebid?.bidder?.alias = new Generic()
        }
        enabledReturnAllBidStatus()
    }
}


and: "Set up openx bidder response with delay"
openXBidder.reset()
openXBidder.setResponseWithDelay(2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number

assert openXAliasBidderRequests.size() == 1

and: "PBs repose shouldn't contain response body from openX bidder"
assert !bidResponse?.ext?.debug?.httpcalls[OPENX]?.responseBody
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actual

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Functional or other tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants